package com.sk.sk_frame_cloud.annotation.aspect;

import com.sk.sk_frame_cloud.annotation.DynamicDataSource;
import com.sk.sk_frame_cloud.config.DynamicDataSourceHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * @Author jiaok
 * @Date 2023-12-19 17:16
 */
@Aspect
@Component
public class DynamicDataSourceAspect {

    /**
     * 设置动态数据源切点
     */
    @Pointcut("@annotation(com.sk.sk_frame_cloud.annotation.DynamicDataSource)")
    public void dynamicSourcePointCut(){

    }

    /**
     * 环绕通知
     * @param joinPoint 切点
     * @return
     * @throws Throwable
     */
    @Around("dynamicSourcePointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws  Throwable{
        //获取切点的值
        String key = getDefineAnnotation(joinPoint).value();
        DynamicDataSourceHolder.setDynamicDataSourceKey(key);
        try {
            return joinPoint.proceed();
        } finally {
            DynamicDataSourceHolder.removeDynamicDataSourceKey();
        }
    }


    /**
     * 判断注解是在方法上还是类上
     * @param joinPoint 切点
     * @return
     */
    private DynamicDataSource getDefineAnnotation(ProceedingJoinPoint joinPoint){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        DynamicDataSource switchDataSource = methodSignature.getMethod().getAnnotation(DynamicDataSource.class);
        if (Objects.nonNull(methodSignature)){
            //说明是方法上的注解
            return switchDataSource;
        }else {
            Class<?> dsClass = joinPoint.getTarget().getClass();
            return dsClass.getAnnotation(DynamicDataSource.class);
        }
    }


}
